package com.ec.bl.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ec.bl.domain.dto.RefundApprovalRequest;
import com.ec.bl.domain.dto.RefundQueryRequest;
import com.ec.bl.domain.dto.RefundRecordDTO;
import com.ec.bl.domain.dto.RefundRequest;
import com.ec.api.domain.po.Bill;
import com.ec.bl.domain.entity.RefundRecord;
import com.ec.bl.mapper.BillMapper;
import com.ec.bl.mapper.RefundRecordMapper;

import com.ec.bl.service.RefundRecordService;
import com.ec.common.domain.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class RefundRecordServiceImpl extends ServiceImpl<RefundRecordMapper, RefundRecord> implements RefundRecordService {

    private final RefundRecordMapper refundRecordMapper;
    private final BillMapper billMapper;

    // RefundRecordServiceImpl.java 中的缓存实现
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final String REFUND_CACHE_KEY = "refund:";
    private static final String REFUND_PAGE_CACHE_KEY = "refund:page:";
    private static final String REFUND_USER_CACHE_KEY = "refund:user:";
    private static final int CACHE_EXPIRE_SECONDS = 300; // 5分钟

    @Override
    @Transactional
    public Result<Long> createRefundRequest(RefundRequest request) {
        // 原有逻辑...
        Bill bill = billMapper.selectById(request.getBillId());
        if (bill == null) {
            return Result.error("账单不存在");
        }

        if (!"paid".equals(bill.getStatus())) {
            return Result.error("只有已支付的账单才能申请退款");
        }

        if (request.getAmount().compareTo(bill.getTotalAmount()) > 0) {
            return Result.error("退款金额不能超过账单金额");
        }

        RefundRecord refundRecord = new RefundRecord()
                .setCreatedAt(LocalDateTime.now())
                .setBillId(request.getBillId())
                .setElderlyUserId(request.getElderlyUserId())
                .setAmount(request.getAmount())
                .setReason(request.getReason())
                .setStatus(RefundRecord.RefundStatus.PENDING);

        boolean saved = this.save(refundRecord);
        if (saved) {
            // 清除相关缓存
            clearRefundCache(request.getElderlyUserId());
            return Result.ok(refundRecord.getId());
        }
        return Result.error("创建退款申请失败");
    }

    @Override
    public Result<IPage<RefundRecordDTO>> getRefundRecordPage(RefundQueryRequest query) {
        // 构建缓存key
        String cacheKey = REFUND_PAGE_CACHE_KEY + query.getPageNum() + ":" + query.getPageSize() + ":" +
                (query.getElderlyUserId() != null ? query.getElderlyUserId() : "all") + ":" +
                (query.getStatus() != null ? query.getStatus() : "all");

        // 从缓存中获取
        String cachedResult = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedResult != null && !cachedResult.isEmpty()) {
            try {
                // 使用具体的Page类型进行反序列化
                Page<RefundRecordDTO> result = JSON.parseObject(cachedResult, new TypeReference<Page<RefundRecordDTO>>() {});
                if (result != null) {
                    return Result.ok(result);
                }
            } catch (Exception e) {
                stringRedisTemplate.delete(cacheKey);
            }
        }

        // 从数据库查询
        Page<RefundRecordDTO> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<RefundRecordDTO> result = refundRecordMapper.selectRefundRecordPage(page, query);

        // 存入缓存
        if (result != null) {
            try {
                stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
            } catch (Exception e) {
            }
        }

        return Result.ok(result);
    }

    @Override
    public Result<RefundRecordDTO> getRefundRecordById(Long id) {
        String cacheKey = REFUND_CACHE_KEY + id;

        // 从缓存中获取
        String cachedRefund = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedRefund != null && !cachedRefund.isEmpty()) {
            try {
                RefundRecordDTO refundRecord = JSON.parseObject(cachedRefund, RefundRecordDTO.class);
                if (refundRecord != null) {
                    return Result.ok(refundRecord);
                }
            } catch (Exception e) {
                stringRedisTemplate.delete(cacheKey);
            }
        }

        // 从数据库查询
        RefundRecordDTO refundRecord = refundRecordMapper.selectRefundRecordById(id);
        if (refundRecord == null) {
            return Result.error("退款记录不存在");
        }

        // 存入缓存
        try {
            stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(refundRecord), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
        } catch (Exception e) {
        }

        return Result.ok(refundRecord);
    }

    @Override
    public Result<List<RefundRecordDTO>> getRefundRecordsByUserId(Long elderlyUserId) {
        String cacheKey = REFUND_USER_CACHE_KEY + elderlyUserId;

        // 从缓存中获取
        String cachedRecords = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedRecords != null && !cachedRecords.isEmpty()) {
            try {
                List<RefundRecordDTO> records = JSON.parseArray(cachedRecords, RefundRecordDTO.class);
                if (records != null) {
                    return Result.ok(records);
                }
            } catch (Exception e) {
                stringRedisTemplate.delete(cacheKey);
            }
        }

        // 从数据库查询
        List<RefundRecordDTO> records = refundRecordMapper.selectRefundRecordsByUserId(elderlyUserId);

        // 存入缓存
        if (records != null) {
            try {
                stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(records), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
            } catch (Exception e) {
            }
        }

        return Result.ok(records);
    }

    @Override
    @Transactional
    public Result<Boolean> approveRefundRequest(RefundApprovalRequest request) {
        // 原有逻辑...
        RefundRecord refundRecord = this.getById(request.getRefundId());
        if (refundRecord == null) {
            return Result.error("退款记录不存在");
        }

        if (!RefundRecord.RefundStatus.PENDING.equals(refundRecord.getStatus())) {
            return Result.error("只有待审核的退款申请才能进行审核");
        }

        RefundRecord.RefundStatus newStatus;
        if ("approved".equals(request.getStatus())) {
            newStatus = RefundRecord.RefundStatus.APPROVED;
        } else if ("rejected".equals(request.getStatus())) {
            newStatus = RefundRecord.RefundStatus.REJECTED;
        } else {
            return Result.error("无效的审核状态");
        }

        refundRecord.setStatus(newStatus);
        boolean updated = this.updateById(refundRecord);

        if (updated) {
            // 清除相关缓存
            clearRefundCache(refundRecord.getElderlyUserId());
            stringRedisTemplate.delete(REFUND_CACHE_KEY + request.getRefundId());
        }

        return updated ? Result.ok(true) : Result.error("审核失败");
    }

    @Override
    @Transactional
    public Result<Boolean> completeRefund(Long refundId) {
        // 原有逻辑...
        RefundRecord refundRecord = this.getById(refundId);
        if (refundRecord == null) {
            return Result.error("退款记录不存在");
        }

        if (!RefundRecord.RefundStatus.APPROVED.equals(refundRecord.getStatus())) {
            return Result.error("只有已审核通过的退款申请才能完成退款");
        }

        refundRecord.setStatus(RefundRecord.RefundStatus.COMPLETED);
        refundRecord.setRefundTime(LocalDateTime.now());

        boolean updated = this.updateById(refundRecord);

        if (updated) {
            // 清除相关缓存
            clearRefundCache(refundRecord.getElderlyUserId());
            stringRedisTemplate.delete(REFUND_CACHE_KEY + refundId);
        }

        return updated ? Result.ok(true) : Result.error("完成退款失败");
    }

    @Override
    @Transactional
    public Result<Boolean> deleteRefundRecord(Long id) {
        // 原有逻辑...
        RefundRecord refundRecord = this.getById(id);
        if (refundRecord == null) {
            return Result.error("退款记录不存在");
        }

        if (!RefundRecord.RefundStatus.PENDING.equals(refundRecord.getStatus()) &&
                !RefundRecord.RefundStatus.REJECTED.equals(refundRecord.getStatus())) {
            return Result.error("只有待审核或已拒绝的退款记录才能删除");
        }

        boolean deleted = this.removeById(id);

        if (deleted) {
            // 清除相关缓存
            clearRefundCache(refundRecord.getElderlyUserId());
            stringRedisTemplate.delete(REFUND_CACHE_KEY + id);
        }

        return deleted ? Result.ok(true) : Result.error("删除失败");
    }

    // 清除退款相关缓存
    private void clearRefundCache(Long elderlyUserId) {
        // 清除用户退款记录缓存
        stringRedisTemplate.delete(REFUND_USER_CACHE_KEY + elderlyUserId);

        // 清除分页缓存（使用模糊匹配）
        Set<String> keys = stringRedisTemplate.keys(REFUND_PAGE_CACHE_KEY + "*");
        if (keys != null && !keys.isEmpty()) {
            stringRedisTemplate.delete(keys);
        }
    }

    // 通用的缓存工具方法
    private void safeDeleteCache(String key) {
        try {
            stringRedisTemplate.delete(key);
        } catch (Exception e) {
            // 记录日志，但不影响主要业务流程
        }
    }

    private void safeBatchDeleteCache(Set<String> keys) {
        try {
            if (keys != null && !keys.isEmpty()) {
                stringRedisTemplate.delete(keys);
            }
        } catch (Exception e) {
        }
    }

}
